#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netdb.h>

int connect_server(const char *ip)
{
	struct addrinfo hints, *result;
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_INET;
	hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = 0;

	if (getaddrinfo(ip, "23", &hints, &result) < 0) {
		return 0;
	}

	int fd = 0;
	for (struct addrinfo *rp = result; rp; rp = rp->ai_next) {
		fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
		if (fd < 0) {
			continue;
		}
		if (connect(fd, rp->ai_addr, rp->ai_addrlen) < 0) {
			close(fd);
			fd = 0;
			continue;
		}
		break;
	}
	freeaddrinfo(result);
	return fd;
}

#define WILL 251
#define DO 253
#define WONT 252
#define DONT 254
#define IAC 255

void deal_contrl(int fd)
{
	u_char buf[512], out[512], data[512];
	int len = 0, olen = 0, dlen = 0;
	while ((len = read(fd, buf, sizeof(buf))) > 0) {
		for (int i = 0; i < len; i++) {
			fprintf(stderr, "%u ", buf[i]);
		}
		for (int i = 0; i < len; i++) {
			if (buf[i] == IAC) {
				out[olen++] = buf[i++];

				switch (buf[i]) {
				case WILL:
					out[olen++] = DO;
					i++;
					out[olen++] = buf[i];
					break;
				case DO:
					out[olen++] = WILL;
					i++;
					out[olen++] = buf[i];
					break;
				case WONT:
					out[olen++] = DONT;
					i++;
					out[olen++] = buf[i];
					break;
				case DONT:
					out[olen++] = WONT;
					i++;
					out[olen++] = buf[i];
					break;
				default:
					continue;
				}
			} else {
				data[dlen++] = buf[i];
			}
		}
		write(fd, out, olen);
		olen = 0;
		if (dlen) {
			break;
		}
	}
	printf("\nout\n");
	for (int i = 0; i < olen; i++) {
		fprintf(stderr, "%u ", out[i]);
	}
	printf("\ndata\n");
	for (int i = 0; i < dlen; i++) {
		fprintf(stderr, "%u ", data[i]);
	}
	pause();
}

int main()
{
	int fd = connect_server("192.168.10.1");
	deal_contrl(fd);
	int len = 0;
	char buf[1024];
	while ((len = read(fd, buf, sizeof(buf))) > 0) {
		buf[len] = 0;
		fprintf(stderr, "%s", buf);
	}

	return 0;
}